#pragma once

#include "SocketIO.h"
#include "Socket.h"
#include "InetAddr.h"

#include <memory>
#include <functional>

using std::shared_ptr;
using std::function;

class EventLoop;
class TcpConnection : public std::enable_shared_from_this<TcpConnection>
{
public:
    using TcpConnectionPtr = shared_ptr<TcpConnection>;
    using TcpConnectionCallback = function<void(const TcpConnectionPtr &)>;

    TcpConnection(int fd, EventLoop *loop);
    ~TcpConnection();
    void send(const string &msg);
    string receive();
    string toString();

    bool isClose() const;

    InetAddr getLocalAddr();
    InetAddr getPeerAddr();

    // 事件注册
    void setNewConnectionCallback(const TcpConnectionCallback &cb);
    void setMessageCallback(const TcpConnectionCallback &cb);
    void setCloseCallback(const TcpConnectionCallback &cb);

    // 事件处理
    void handleNewConnection();
    void handleMessage();
    void handleClose();

    // 注册TcpConnection::send 交给EventLoop的_pengdings任务队列执行
    // 业务函数通过TcpConnectionPtr调用 将消息msg发送到客户端
    void sendInLoop(const string &msg);
private:
    SocketIO _socketIO;
    Socket _socket;
    InetAddr _lAddr; // 本地ip
    InetAddr _pAddr; // 对端ip

    TcpConnectionCallback _onNewConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;

    EventLoop *_loop;
};
